var Config = function() {
	this.logger = new Logger("Config");
	var filterMap = {};
	// include pattern -> id (*..1)
	var includeRegexMap = {};

	// get filter function from current document URL, O(n), need improve
	this.getFilter = function(docLoc) {
		var filter = null;
		// check if excluded;
		for (var key in includeRegexMap) {
			// key is regex string
			var regex = new RegExp(key, "gi");
			if (regex.test(docLoc)) {// got match
				var id = includeRegexMap[key];
				filter = filterMap[id];
				var excs = filter.excludes;
				// has exclude pattern and docLoc matched
				for (var i = 0; i < excs.length; i++) {
					var exregex = new RegExp(excs[i], "gi");
					exregex.lastIndex = 0;
					if (exregex.test(docLoc)) {
						// excluded
						filter = null;
						break;
					}
				}
				break;
			}
		}
		return filter;
	}

	this.load = function() {
		function parsePatterns(node) {
			var patterns = new Array();
			for (var i = 0, childNode = null; (childNode = node.childNodes[i]); i++) {
				if (childNode.nodeName == "Pattern") {
					var value = childNode.firstChild.nodeValue;
					try {
						// test regexp is correct
						var regexp = new RegExp(value, "gi");
						patterns.push(value);
					} catch (err) {
						this.logger.warn("error create RegExp for: "
								+ childNode.firstChild.nodeValue, err);
					}
				}
			}
			return patterns;
		}
		var domParser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
				.createInstance(Components.interfaces.nsIDOMParser);

		var configContents = getContents(getScriptFileURI("config.xml"));
		var doc = domParser.parseFromString(configContents, "text/xml");
		var nodes = doc.evaluate("/VILPlusConfig/Filter", doc, null, 0, null);

		if (filterMap) {
			delete filterMap;
			filterMap = {};
		}

		for (var node = null; (node = nodes.iterateNext());) {
			var filter = {};

			for (var i = 0, childNode = null; (childNode = node.childNodes[i]); i++) {
				if (childNode.nodeName == "Includes") {
					filter.includes = parsePatterns(childNode);
				} else if (childNode.nodeName == "Excludes") {
					filter.excludes = parsePatterns(childNode);
				} else if (childNode.nodeName == "Function") {
					filter.filter = childNode.firstChild.nodeValue;
				}
			}

			filter.id = node.getAttribute("id");
			filter.enabled = node.getAttribute("enabled") == true.toString();

			filterMap[filter.id] = filter;
			for (var i = 0; i < filter.includes.length; i++) {
				var increg = filter.includes[i];
				if (includeRegexMap[increg]) {
					this.logger.warn("duplicate regexp skipped: " + increg
							+ " for id: " + includeRegexMap[increg] + " and "
							+ filter.id);
					continue;
				}
				includeRegexMap[increg] = filter.id;
			}
		}
	}
}